package com.neuedu.boot.sso;

import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neuedu.boot.config.CommonResult;
import com.neuedu.boot.entity.User;
import com.neuedu.boot.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.ZoneId;

@Component //ioc容器中的组件
public class SSOInterceptor implements HandlerInterceptor {

    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    RedisService redisService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        //        拿到token 之后，解析token，  跟缓存对比，如果缓存中存在，
        //        拿到token，解析出来用户id，username，如果能解析就暂时认为他是已经登录（其实是有问题的，客户端可以伪造token）
        if (ObjectUtils.isEmpty(token)) {
            notoken(response);
            return false;
        }
        DecodedJWT decode = JWT.decode(token);
        Integer userid = decode.getClaim("userId").asInt();
        String username = decode.getClaim("username").asString();
        long lastLogin = decode.getClaim("lastlogin").asLong();

        //如果查询redis中不存在对应的登录信息，
        if (userid == null) {
            notoken(response);
            return false;
        }

        //查找redis中是否存在key

        String key = "LOGIN_INFO_" + username;
        String json = (String)redisService.get(key);
        if(ObjectUtils.isEmpty(json)){
            notoken(response);
            return false;
        }

        User user = objectMapper.readValue(json, User.class);

        //跟缓存中的最后一次登录时间进行比较，如果不一致也说明token
        long longLastlogin = user.getLastlogin().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
        if(lastLogin != longLastlogin){
            notoken(response);
            return false;
        }

        //更新最大存活时间
        redisService.expire(key,1800);


        return true;
    }


    //无效的token 或者超时
    private void notoken(HttpServletResponse response) throws IOException {
        response.setContentType("text/application;charset=utf-8");
        CommonResult notoken = CommonResult.notoken();
        String result = objectMapper.writeValueAsString(notoken);
        PrintWriter out = response.getWriter();
        out.write(result);
        out.flush();
        out.close();

        //notoken
    }

    //    @Override
    //    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    //
    //    }
    //
    //    @Override
    //    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    //
    //    }

    public static void main(String[] args) {

        char a = 'a';
        System.out.println("(int)a = " + (int) a);


    }
}
